package ru.yelbota.flex.as3jobs.libs {

import flash.utils.Dictionary;

import ru.yelbota.flex.as3jobs.Job;
import ru.yelbota.flex.as3jobs.as3_jobs;
import ru.yelbota.flex.as3jobs.exceptions.JobSimpleResourceException;

use namespace as3_jobs;

public class SideEffectUtils {

    public static var lastArgsId:uint = 0;

    public static var argRegistry:Dictionary = new Dictionary(true);

    public static function getObjectUniqueId(arg:*):uint {
        var id:* = argRegistry[arg];
        if (id == null) id = argRegistry[arg] = lastArgsId++;
        return id;
    }

    public static function getStringDJB2Hash(string:String):uint {
       var hash:uint = 5381;
       for (var i:int = 0; i < string.length; i++)
           hash = ((hash << 5) + hash) ^ string.charCodeAt(i);
        return hash;
    }

    //--------------------------------------------------------------------------
    //
    //  Public methods
    //
    //--------------------------------------------------------------------------

    public static function saveState(thisObject:Object, f:Function, args:Array):* {

        Job.incrementCallIndex();

        var rId:String = "Memoizator$" + Job.getCurrentCallIndex();
        var resource:* = Job.getResource(Job.getCurrentJob(), rId);

        if (resource == null) {
            resource = f.apply(thisObject, args);
            if (resource == undefined) // if function returns void
                resource = 1;
            throw new JobSimpleResourceException(resource, rId);
        }

        return resource;
    }
}

}
